import * as Cesium from 'cesium';

export class CameraManager {
  constructor(cesiumManager) {
    this.cesiumManager = cesiumManager;
    this.viewer = cesiumManager.viewer;
    this.camera = this.viewer.camera;
    this.cameraPaths = new Map(); // 存储相机路径
    this.isAnimating = false; // 动画状态
  }

  /**
   * 飞行到指定位置
   * @param {Object} options - 飞行选项
   * @param {Object} options.destination - 目标位置 {longitude, latitude, height}
   * @param {Number} options.duration - 飞行持续时间(秒)
   * @param {Object} options.orientation - 相机方向 {heading, pitch, roll}
   * @returns {Promise} 飞行完成的Promise
   */
  flyTo(options) {
    return new Promise((resolve, reject) => {
      if (!this.viewer) {
        reject(new Error('Viewer is not initialized'));
        return;
      }

      const flyOptions = {
        destination: Cesium.Cartesian3.fromDegrees(
          options.destination.longitude,
          options.destination.latitude,
          options.destination.height || 1000
        ),
        duration: options.duration || 3.0,
        orientation: options.orientation || {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-30),
          roll: 0.0
        },
        complete: () => resolve(),
        cancel: () => reject(new Error('Flight was cancelled'))
      };

      this.camera.flyTo(flyOptions);
    });
  }

  /**
   * 设置相机视角
   * @param {Object} options - 视角选项
   * @param {Object} options.position - 相机位置 {longitude, latitude, height}
   * @param {Object} options.orientation - 相机方向 {heading, pitch, roll}
   */
  setView(options) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    this.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(
        options.position.longitude,
        options.position.latitude,
        options.position.height || 1000
      ),
      orientation: options.orientation || {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-30),
        roll: 0.0
      }
    });
  }

  /**
   * 相机看向指定目标
   * @param {Object} target - 目标位置 {longitude, latitude, height}
   * @param {Object} options - 选项
   */
  lookAt(target, options = {}) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    const targetPosition = Cesium.Cartesian3.fromDegrees(
      target.longitude,
      target.latitude,
      target.height || 0
    );

    const defaultOffset = new Cesium.HeadingPitchRange(
      Cesium.Math.toRadians(options.heading || 0),
      Cesium.Math.toRadians(options.pitch || -30),
      options.range || 1000
    );

    this.camera.lookAt(targetPosition, defaultOffset);
  }

  /**
   * 取消lookAt状态
   */
  cancelLookAt() {
    this.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
  }

  /**
   * 创建相机路径
   * @param {String} name - 路径名称
   * @param {Array} positions - 位置数组 [{longitude, latitude, height}, ...]
   * @returns {Cesium.CameraPath} 相机路径对象
   */
  createCameraPath(name, positions) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    const cartesianPositions = positions.map(pos => 
      Cesium.Cartesian3.fromDegrees(pos.longitude, pos.latitude, pos.height || 1000)
    );

    const property = new Cesium.SampledPositionProperty();
    positions.forEach((pos, index) => {
      const time = new Cesium.JulianDate.fromIso8601(`2023-01-01T${String(index).padStart(2, '0')}:00:00Z`);
      property.addSample(time, cartesianPositions[index]);
    });

    const cameraPath = {
      positions: cartesianPositions,
      property: property
    };

    this.cameraPaths.set(name, cameraPath);
    return cameraPath;
  }

  /**
   * 沿路径飞行
   * @param {String} pathName - 路径名称
   * @param {Object} options - 飞行选项
   * @returns {Promise} 飞行完成的Promise
   */
  flyAlongPath(pathName, options = {}) {
    const path = this.cameraPaths.get(pathName);
    if (!path) {
      throw new Error(`Camera path "${pathName}" not found`);
    }

    return new Promise((resolve) => {
      const startTime = new Cesium.JulianDate.now();
      const endTime = Cesium.JulianDate.addSeconds(
        startTime, 
        options.duration || 10, 
        new Cesium.JulianDate()
      );

      this.viewer.clock.startTime = startTime;
      this.viewer.clock.stopTime = endTime;
      this.viewer.clock.currentTime = startTime;
      this.viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
      this.viewer.clock.multiplier = 1;

      // 创建位置插值
      const position = new Cesium.SampledPositionProperty();
      const numberOfPoints = path.positions.length;
      
      for (let i = 0; i < numberOfPoints; i++) {
        const time = Cesium.JulianDate.addSeconds(
          startTime,
          (i / (numberOfPoints - 1)) * (options.duration || 10),
          new Cesium.JulianDate()
        );
        position.addSample(time, path.positions[i]);
      }

      // 创建实体来跟随路径
      const entity = this.viewer.entities.add({
        position: position,
        orientation: new Cesium.VelocityOrientationProperty(position),
        // 可以添加一个点来可视化路径跟随
        point: {
          pixelSize: 10,
          color: Cesium.Color.RED,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 2
        }
      });

      // 设置相机跟随实体
      this.viewer.trackedEntity = entity;

      // 设置定时器在完成后清理
      setTimeout(() => {
        this.viewer.entities.remove(entity);
        this.viewer.trackedEntity = undefined;
        resolve();
      }, (options.duration || 10) * 1000);
    });
  }

  /**
   * 开始旋转相机
   * @param {Object} options - 旋转选项
   * @returns {Function} 停止旋转的函数
   */
  startRotating(options = {}) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    const defaultOptions = {
      speed: 0.01, // 弧度/帧
      direction: 'right', // 'left' 或 'right'
      pivot: null // 旋转中心点 {longitude, latitude, height}
    };

    const rotateOptions = Object.assign({}, defaultOptions, options);
    
    // 如果指定了旋转中心点
    if (rotateOptions.pivot) {
      const pivotPosition = Cesium.Cartesian3.fromDegrees(
        rotateOptions.pivot.longitude,
        rotateOptions.pivot.latitude,
        rotateOptions.pivot.height || 0
      );
      
      // 设置相机围绕该点旋转
      this.camera.lookAt(pivotPosition, new Cesium.Cartesian3(0.0, -1000.0, 0.0));
    }

    let rotating = true;
    
    const rotate = () => {
      if (!rotating) return;
      
      if (rotateOptions.pivot) {
        // 围绕中心点旋转
        this.camera.rotateRight(rotateOptions.direction === 'right' ? 
          rotateOptions.speed : -rotateOptions.speed);
      } else {
        // 自转
        this.camera.rotateRight(rotateOptions.direction === 'right' ? 
          rotateOptions.speed : -rotateOptions.speed);
      }
      
      requestAnimationFrame(rotate);
    };
    
    rotate();
    
    // 返回停止函数
    return () => {
      rotating = false;
      if (rotateOptions.pivot) {
        this.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
      }
    };
  }

  /**
   * 相机震动效果
   * @param {Object} options - 震动选项
   * @returns {Promise} 震动完成的Promise
   */
  shake(options = {}) {
    return new Promise((resolve) => {
      if (!this.viewer) {
        resolve();
        return;
      }

      const defaultOptions = {
        intensity: 0.5, // 震动强度
        duration: 1000, // 持续时间(毫秒)
        speed: 50 // 震动速度(毫秒)
      };

      const shakeOptions = Object.assign({}, defaultOptions, options);
      
      const originalPosition = Cesium.Cartesian3.clone(this.camera.position);
      const startTime = Date.now();
      let shaking = true;

      const shakeCamera = () => {
        if (!shaking) return;
        
        const elapsed = Date.now() - startTime;
        if (elapsed > shakeOptions.duration) {
          // 恢复原始位置
          this.camera.position = originalPosition;
          resolve();
          return;
        }

        // 计算震动偏移
        const offsetX = (Math.random() - 0.5) * shakeOptions.intensity;
        const offsetY = (Math.random() - 0.5) * shakeOptions.intensity;
        const offsetZ = (Math.random() - 0.5) * shakeOptions.intensity;

        // 应用震动
        const newPosition = Cesium.Cartesian3.clone(originalPosition);
        newPosition.x += offsetX;
        newPosition.y += offsetY;
        newPosition.z += offsetZ;
        
        this.camera.position = newPosition;

        setTimeout(shakeCamera, shakeOptions.speed);
      };

      shakeCamera();
      
      // 提供外部停止方法
      return () => {
        shaking = false;
        this.camera.position = originalPosition;
        resolve();
      };
    });
  }

  /**
   * 保存当前相机状态
   * @param {String} name - 状态名称
   * @returns {Object} 相机状态
   */
  saveCameraState(name) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    const state = {
      position: Cesium.Cartographic.fromCartesian(this.camera.position),
      heading: this.camera.heading,
      pitch: this.camera.pitch,
      roll: this.camera.roll
    };

    if (name) {
      localStorage.setItem(`cameraState_${name}`, JSON.stringify({
        longitude: Cesium.Math.toDegrees(state.position.longitude),
        latitude: Cesium.Math.toDegrees(state.position.latitude),
        height: state.position.height,
        heading: state.heading,
        pitch: state.pitch,
        roll: state.roll
      }));
    }

    return state;
  }

  /**
   * 恢复相机状态
   * @param {String|Object} nameOrState - 状态名称或状态对象
   */
  restoreCameraState(nameOrState) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    let state;
    if (typeof nameOrState === 'string') {
      const savedState = localStorage.getItem(`cameraState_${nameOrState}`);
      if (!savedState) {
        throw new Error(`Camera state "${nameOrState}" not found`);
      }
      state = JSON.parse(savedState);
      state.position = Cesium.Cartographic.fromDegrees(
        state.longitude,
        state.latitude,
        state.height
      );
    } else {
      state = nameOrState;
    }

    this.camera.setView({
      destination: Cesium.Cartesian3.fromRadians(
        state.position.longitude,
        state.position.latitude,
        state.position.height
      ),
      orientation: {
        heading: state.heading,
        pitch: state.pitch,
        roll: state.roll
      }
    });
  }

  /**
   * 锁定相机到实体
   * @param {Entity} entity - 要锁定的实体
   */
  lockToEntity(entity) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    this.viewer.trackedEntity = entity;
  }

  /**
   * 解锁相机
   */
  unlockCamera() {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    this.viewer.trackedEntity = undefined;
  }

  /**
   * 设置相机边界限制
   * @param {Object} rectangle - 限制矩形 {west, south, east, north}
   */
  setBoundaryLimit(rectangle) {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    this.camera.setView({
      destination: Cesium.Rectangle.fromDegrees(
        rectangle.west,
        rectangle.south,
        rectangle.east,
        rectangle.north
      )
    });

    // 设置相机边界
    this.viewer.scene.screenSpaceCameraController.enableTranslate = true;
    this.viewer.scene.screenSpaceCameraController.enableZoom = true;
    this.viewer.scene.screenSpaceCameraController.enableRotate = true;
    this.viewer.scene.screenSpaceCameraController.enableTilt = true;
  }

  /**
   * 重置相机限制
   */
  resetBoundaryLimit() {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    // 移除相机边界限制
    this.viewer.scene.screenSpaceCameraController.enableTranslate = true;
    this.viewer.scene.screenSpaceCameraController.enableZoom = true;
    this.viewer.scene.screenSpaceCameraController.enableRotate = true;
    this.viewer.scene.screenSpaceCameraController.enableTilt = true;
  }

  /**
   * 获取相机当前状态
   * @returns {Object} 相机状态信息
   */
  getCameraInfo() {
    if (!this.viewer) {
      throw new Error('Viewer is not initialized');
    }

    const position = Cesium.Cartographic.fromCartesian(this.camera.position);
    
    return {
      position: {
        longitude: Cesium.Math.toDegrees(position.longitude),
        latitude: Cesium.Math.toDegrees(position.latitude),
        height: position.height
      },
      orientation: {
        heading: this.camera.heading,
        pitch: this.camera.pitch,
        roll: this.camera.roll
      },
      direction: this.camera.direction,
      up: this.camera.up,
      right: this.camera.right
    };
  }

  /**
   * 销毁相机管理器
   */
  destroy() {
    this.cameraPaths.clear();
    // 清理可能正在进行的动画
    this.isAnimating = false;
  }
}